package codename.carrot.bomberman.views;

import sheep.game.Sprite;
import sheep.graphics.Image;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import codename.carrot.bomberman.AppStorage;
import codename.carrot.bomberman.AppStorage.Power;
import codename.carrot.bomberman.R;
import codename.carrot.bomberman.game.listener.PlayerLifeListener;
import codename.carrot.bomberman.game.listener.PlayerPowerUpListener;
import codename.carrot.bomberman.models.Player;

/**
 * A class that draws the visual information regarding player nickname, and the current power-ups
 * which the player has acquired
 * @author Gruppe A4 
 */
public class GameVisualContainer implements PlayerLifeListener, PlayerPowerUpListener{

	/**
	 * Icon for health stats.
	 */
	private Sprite healthIcon; 
	/**
	 * The bounding rectangle of the information bar at the top of the game.
	 */
	private Rect playerInformationBar;
	/**
	 * The paint method for styling the box.
	 */
	private Paint playerInformationBarPaint;
	/**
	 * The bounding rectangle of number of lives left.
	 */
	private Rect healthTextRect;
	/**
	 * Used to position number to power-up
	 */
	private float buffImageHeight;
	/**
	 * The width of all images in the visual container.
	 */
	private float buffImageWidth;
	/**
	 * The icon for bomb stats.
	 */
	
	private Sprite bombStatsIcon;

	
	/**
	 * The bounding rectangle for the number of bombs.
	 */
	private Rect bombTextRect;

	
	/**
	 * The bounding rectangle for explosion text.
	 */
	private Sprite explosiveStatsIcon;

	/**
	 * Used to position number to power-up
	 */
	private Rect explosiveTextRect;

	
	/**
	 * The boudning rectangle for speed ups.
	 */
	private Sprite speedStatsIcon;

	
	/**
	 * Used to position number to power-up
	 */
	private Rect speedTextRect;

	
	/**
	 * Used to display number of health left by showing only 1 number from 
	 * the number sprite. Everytime a life is lost, this Rect will move one spot
	 * to the left shifting the number down by 1, eg from 9 to 8.
	 */
	
	private Rect healthNumberSource;

	/**
	  * Used to display number of bomb power-up by showing only 1 number from 
	 * the number sprite. 
	 */
	private Rect bombNumberSource;

	
	/**
	 * Used to display number of explotion power-up by showing only 1 number from 
	 * the number sprite
	 */
	private Rect explosionNumberSource;

	
	/**
	 * Used to display number of speed power-up by showing only 1 number from 
	 * the number sprite
	 */
	private Rect speedNumberSource;

	
	/**
	 * The bitmap that contain the numbers from -9 to 9
	 */
	private Bitmap numberBitmap;

	/**
	 * The width of each number in the numberBitmap
	 */
	private int numberImageWidth;

	
	/**
	 * Used to display the nickname of the player
	 */
	private String playerNickName;

	
	/**
	 * Used to paint the playerNickName string onto the canvas
	 */
	private Paint playerNamePaint;


	/**
	 * @param playerStartLife number of life the player starts with.
	 * @param playerStartBomb number of bomb power-up the player start with.
	 * @param playerStartExplosion number of explotion power-up the player start with.
	 * @param playerStartSpeed number of speed power-up the player start with.
	 * @param playerName the nickname of the player.
	 */
	public GameVisualContainer(int playerStartLife, int playerStartBomb, int playerStartExplosion,int playerStartSpeed, String playerName){
		numberBitmap  = BitmapFactory.decodeResource(AppStorage.droidGame.getResources(), R.drawable.number_sprite_sheet_minus9_to_9);
		createPlayerInformationbar();
		createNumberSourceRects();
		createHealthIcon();
		createBombBuffIcon();
		createExplisionBuffIcon();
		createSpeedBuffIcon();
		playerNamePaint = new Paint();
		playerNamePaint.setColor(Color.BLACK);
		playerNamePaint.setTextSize(buffImageHeight);
		this.setPlayerName(playerName);
		this.setPlayerStartBombs(playerStartBomb);
		this.setPlayerStartLife(playerStartLife);
		this.setPlayerStartExplosion(playerStartExplosion);
		this.setPlayerStartSpeed(playerStartSpeed);
		
		
	}
	
	/**
	 *  Creates the health-icon representing the life of the player
	 */
	private void createHealthIcon(){
		Image img = new Image(R.drawable.icon_hp);
		buffImageHeight = img.getHeight();
		buffImageWidth = img.getWidth();
		healthIcon = new Sprite(img);
		healthIcon.setPosition(playerInformationBar.width()/3.0f,playerInformationBar.centerY());
		healthTextRect = new Rect((int)(healthIcon.getX()+buffImageWidth), playerInformationBar.centerY()-(int)(buffImageHeight/2), 
				(int)(healthIcon.getX()+buffImageWidth+numberImageWidth),playerInformationBar.centerY()-(int)(buffImageHeight/2)+(int)buffImageHeight);
	}
	
	/**
	 *  Creates the bomb-up icon
	 */
	private void createBombBuffIcon(){
		Image img = new Image(R.drawable.icon_bomb_buff);
		bombStatsIcon = new Sprite(img);
		bombStatsIcon.setPosition(playerInformationBar.width()/2.0f,playerInformationBar.centerY());
		bombTextRect = new Rect((int) (bombStatsIcon.getX()+buffImageWidth), playerInformationBar.centerY()-(int)(buffImageHeight/2), 
						(int)(bombStatsIcon.getX()+buffImageWidth+numberImageWidth), playerInformationBar.centerY()-(int)(buffImageHeight/2)+(int)buffImageHeight);
		
	}
	
	/**
	 * Creates the explosion icon
	 */
	private void createExplisionBuffIcon(){
		Image img = new Image(R.drawable.icon_explode_buff);
		explosiveStatsIcon = new Sprite(img);
		explosiveStatsIcon.setPosition(playerInformationBar.width()/1.5f,playerInformationBar.centerY());
		explosiveTextRect = new Rect((int) (explosiveStatsIcon.getX()+buffImageWidth), playerInformationBar.centerY()-(int)(buffImageHeight/2), 
				(int)(explosiveStatsIcon.getX()+buffImageWidth+numberImageWidth), playerInformationBar.centerY()-(int)(buffImageHeight/2)+(int)buffImageHeight);

	}
	
	/**
	 *  Creates the speed-icon
	 */
	private void createSpeedBuffIcon(){
		Image img = new Image(R.drawable.icon_speed_buff);
		speedStatsIcon = new Sprite(img);
		speedStatsIcon.setPosition(playerInformationBar.width()/1.2f,playerInformationBar.centerY());
		speedTextRect = new Rect((int) (speedStatsIcon.getX()+buffImageWidth), playerInformationBar.centerY()-(int)(buffImageHeight/2), 
				(int)(speedStatsIcon.getX()+buffImageWidth+numberImageWidth), playerInformationBar.centerY()-(int)(buffImageHeight/2)+(int)buffImageHeight);
	}
		
	/**
	 * Prepare the retangles used to etract number out of the numberBitmap
	 */
	private void createNumberSourceRects(){
		numberImageWidth = Math.round(numberBitmap.getWidth()/19.0f);
		healthNumberSource = new Rect(0, 0, numberImageWidth, numberBitmap.getHeight());
		bombNumberSource = new Rect(0, 0, numberImageWidth, numberBitmap.getHeight());
		explosionNumberSource = new Rect(0, 0, numberImageWidth, numberBitmap.getHeight());
		speedNumberSource= new Rect(0, 0, numberImageWidth, numberBitmap.getHeight());
		
	}
	
	/**
	 *  Sets the nr of lives a player starts with
	 * @param life nr of lives
	 */
	public void setPlayerStartLife(int life){
		healthNumberSource.left = numberImageWidth*9 + (life* numberImageWidth);
		healthNumberSource.right = healthNumberSource.left +numberImageWidth;	
	}
	
	/**
	 *  Sets the initial range of explosion for player
	 * @param range
	 */
	public void setPlayerStartExplosion(int range){
		explosionNumberSource.left = numberImageWidth*9+ (range * numberImageWidth);
		explosionNumberSource.right = explosionNumberSource.left + numberImageWidth;
	}
	
	/**
	 *  Sets the player name
	 * @param name player name
	 */
	public void setPlayerName(String name){
		playerNickName = name;
	}
	
	/**
	 *  Sets the number of bombs the player starts with
	 * @param nrBombs
	 */
	public void setPlayerStartBombs(int nrBombs){
		bombNumberSource.left = numberImageWidth*9+ (nrBombs * numberImageWidth);
		bombNumberSource.right = bombNumberSource.left + numberImageWidth;
	}
	
	/**
	 *  Sets the speed the player starts with
	 * @param speed 
	 */
	public void setPlayerStartSpeed(int speed){
		if(speed < 0)
			speedNumberSource.left = numberImageWidth*(9-speed);
		else
			speedNumberSource.left = numberImageWidth*9 +(speed * numberImageWidth);
		speedNumberSource.right = speedNumberSource.left + numberImageWidth;
	}
	
	/**
	 *  Creates the information-bar with information about the player, and the power-ups
	 */
	private void createPlayerInformationbar(){
		playerInformationBar = new Rect(0, 0,AppStorage.SCREEN_WIDTH_GAME ,(int) (AppStorage.SCREEN_HEIGHT_GAME/10));
		playerInformationBarPaint = new Paint();
		playerInformationBarPaint.setColor(Color.WHITE);
		playerInformationBarPaint.setAlpha(100);
	}
	
	/**
	 *  Draws the player information to the canvas
	 * @param canvas
	 */
	public void draw(Canvas canvas){	
		canvas.drawRect(playerInformationBar, playerInformationBarPaint);
		healthIcon.draw(canvas);
		bombStatsIcon.draw(canvas);
		explosiveStatsIcon.draw(canvas);
		speedStatsIcon.draw(canvas);
		canvas.drawBitmap(numberBitmap, healthNumberSource,healthTextRect, null);
		canvas.drawBitmap(numberBitmap, bombNumberSource, bombTextRect, null);
		canvas.drawBitmap(numberBitmap, explosionNumberSource, explosiveTextRect, null);
		canvas.drawBitmap(numberBitmap, speedNumberSource, speedTextRect, null);
		canvas.drawText(playerNickName, playerInformationBar.left+10, playerInformationBar.centerY()+playerNamePaint.getTextSize()/3, playerNamePaint);
	}
	
	/**
	 *  Updates the state of the sprites to be drawn
	 * @param dt
	 */
	public void update(float dt) {
		healthIcon.update(dt);
		bombStatsIcon.update(dt);
		explosiveStatsIcon.update(dt);
		speedStatsIcon.update(dt);
	}

	  /**
     * Called/invoked when the player has lost a life, and updates local copy of the data
     */
	@Override
	public void playerLostLife(int life, Player player) {
		healthNumberSource.left = numberImageWidth*9 +(life* numberImageWidth);
		healthNumberSource.right = healthNumberSource.left +numberImageWidth;	
	}

	/**
	 * Called/invoked when the speed of the player has changed, and updates local copy of the data
	 */
	@Override
	public void speedChange(int speed, Power power) {
		speedNumberSource.left = numberImageWidth*9+(speed * numberImageWidth);
		speedNumberSource.right = speedNumberSource.left + numberImageWidth;
	}

	 /**
     * Called/invoked when the flame-up of the player has changed, and updates local copy of the data
     */
	@Override
	public void flameChange(int flameLength, Power power) {
		explosionNumberSource.left = numberImageWidth*9+ (flameLength * numberImageWidth);
		explosionNumberSource.right = explosionNumberSource.left + numberImageWidth;
	}

    /**
     * Called/invoked when the bomb-up of the player has changed, and updates local copy of the data
     */
	@Override
	public void bombChange(int bombs, Power power) {
		bombNumberSource.left = numberImageWidth*9+( bombs * numberImageWidth);
		bombNumberSource.right = bombNumberSource.left + numberImageWidth;
	}
	
}
